import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

class MyBlocking {
    private String[] strings = null;
    private int head = 0;
    private int tail = 0;
    private int size = 0;

    public MyBlocking() {

        this(Integer.MAX_VALUE);
    }

    public MyBlocking(int p) {
        strings = new String[p];
    }

    public synchronized void put(String p) throws InterruptedException {

        while (size >= strings.length) {
            this.wait();
        }
        strings[tail] = p;
        tail++;
        if (tail >= strings.length) {
            tail = 0;
        }
        size++;
        this.notify();
    }

    public synchronized String take() throws InterruptedException {

        while (size == 0) {
            this.wait();
        }
        String p = strings[head];
        head++;
        if (head >= strings.length) {
            head = 0;
        }
        size--;
        this.notify();
        return p;
    }
}

public class Demo3 {

    public static MyBlocking myBlocking = new MyBlocking(100);
    public static void main(String[] args) {

        Thread t1 = new Thread(() -> {


                try {
                    int p = 0;
                    while (true) {

                        myBlocking.put(p + "");
                        System.out.println("生产元素：" + p);
                        p++;

                    }

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
        });

        Thread t2 = new Thread(() -> {


                try {
                    String p = null;
                    while (true) {
                        p = myBlocking.take();

                        System.out.println("消费元素：" + p);
                    }

                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
        });
        t1.start();
        t2.start();

    }
}
